package com.tedu.api.list;

import org.junit.Test;

import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;

/**
 * Collection集合下  子集合【叫队列】  包位置：java.util
 * Queue     队列      单端队列
 * Deque     队列      双端队列  Deque接口  --继承-- Queue接口
 * 作用：保存数据，有序存储和处理，功能：数据缓冲或者多线程协调工作！
 *
 * 队列实现类：
 * LinkedList：双向链表
 */
public class QueueAPI {
    //Queue    队列     单端队列
    @Test
    public void testQueue(){
        //创建队列--多态--LinkedList
        Queue<String> queue=new LinkedList<>();
        /**
         * offer()  ----add()一样
         * 作用：入列操作：对尾追加元素
         *
         */
        queue.offer("青花瓷");
        queue.offer("冬眠");
        queue.offer("我的滑板鞋");
        queue.offer("体面");
        System.out.println("Queue队列:"+queue);
        /**
         * poll()
         * 作用：出列操作，获取队首元素，并且删除队列中队首
         * peek（）
         * 作用：出队操作，获取队首元素，不删除队列中队首
         */
        queue.poll();queue.poll();//删除队首元素
        System.out.println("Queue队列："+queue);
        String  str=queue.peek();
        System.out.println("队首元素："+str);
        System.out.println("Queue队列："+queue);
        /**
         * 需求：1.遍历队列---while---只遍历一次队列【队列元素消失】
         *    提示：while 条件：拿到队列中总长度   size（）
         * 需求：2.遍历队列---增强for--队列元素不消失
         *    提示：for  条件：E e：队列
         */
       while(queue.size()>0){//true:队列总数>0  队列有元素  遍历
      str=queue.poll();//获取队首，删除队列中队首
      System.out.println("获取队列元素："+str);

       }
       System.out.println("Queue1队列元素："+queue);
        /**
         * 需求：2.遍历队列--增强for--队列元素不消失
         *   提示：for  条件：E e：数组泛型/集合泛型: 数组引用/集合引用
         */
        for (String e:queue){
            System.out.println("队列元素:"+e);
        }
        System.out.println("Queue队列："+queue);
    }
    //Deque   队列   双端队列--继承--单端队列

    @Test
    public void testDeque(){
        //创建Deque 双端队列  方法基本一致，部分方法不一致
        Deque<String> deque=new LinkedList<>();
        deque.offer("任贤齐");deque.offer("王菲");
        deque.offer("毛阿敏");deque.offer("那英");
        System.out.println("双端队列："+deque);
        //offerFirst()  队首添加元素   OfferLast（） 队尾添加元素
        deque.offerFirst("蔡徐坤"); deque.offerFirst("薛之谦");
        System.out.println("双端队列[首尾添加元素]:"+deque);
        //getFirst()  获取队首  getLast() 获取队尾 【单端：peek类似】
        System.out.println("获取队列中队首:"+deque.getFirst());
        System.out.println("获取队列中队尾:"+deque.getLast());
        //pollFirst() 获取队首：删除队列中队首【单端：poll类似】
        //pollLast（） 获取队尾：删除队列中队尾
        String xue=deque.pollFirst();//删除"薛之谦"元素  队列---队首
        System.out.println("队尾元素："+xue);
        System.out.println("双端队列"+deque);
    }

    /**
     * 栈结构：业务中如果有后退【撤销】情况使用
     * 双端队列支持栈结构--提供相应的方法实现栈结构
     */
    @Test
    public void testStack(){
        //创建双端队列--支持栈结构
        Deque<String> stack=new LinkedList<>();
        /**
         * push（）  Deque  独有的方法--支持栈结构
         * ---offer：Queue---add：Collection接口【添加】
         * 作用：【添加：往栈压入一个元素】  压栈操作
         */
        stack.push("夯大力");
        stack.push("恶搞之家");
        stack.push("喜羊羊与灰太狼");
        stack.push("魔方大厦");
        System.out.println("栈结构"+stack);
        /**
         * pop()  出栈一个尾元素
         */
        String last=stack.pop();
        System.out.println("找出栈结构："+last);
        System.out.println("栈结构:"+ stack);
        //面试题：pop.poll.peek的使用区别？
//        pop、poll和peek是常见的函数果从第一元素删除一个元素），peek这种操作则是不删除元素，只查看元素，它使用迭代器来实现，因此它的时间复杂度为O(n)。pop和poll的区别在于，pop会删除队列或栈顶的元素，因此，当队列或栈为空时，调用pop会引发一个异常；而poll则不会，它只是返回一个零长度的元素，不会引发任何异常。此外，peek操作只用于查看元素，它不会修改或删除元素，也不返回值。
//        在栈和队列中，pop和poll是常用的操作，它们可以实现删除元素或获取队列或栈顶元素的功能。而peek则主要用于查看队列或栈顶元素，而不进行任何修改或删除操作。在实际应用中，根据具体需求，可以选择使用pop、poll或peek来实现不同的功能。
        /**
         * 需求1：遍历栈结构---while---元素出栈，队列元素需要清空
         * 需求2：遍历栈结构---增强for--元素遍历成功，队列元素不变
         */

         while(stack.size()>0) {
             String str=stack.pop();
             System.out.println("出栈 删除栈顶元素："+str);
         }
         System.out.println("stack："+stack);

         for(String e :stack){
             System.out.println("栈结构："+e);
         }
        System.out.println("出栈 删除栈顶元素:"+stack);
    }

    }




















